package com.brainydroid.example.numerical_distance;

import java.io.File;
import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class ServerTalker {

    private static String BS_URL_UPLOAD = "upload/";
    private static String BS_URL_UPLOAD_MAI_PUBKEY = "mai_pubkey/";
    private static String BS_URL_UPLOAD_EA_DATA = "ea_data/";
    private static String BS_URL_UPLOAD_REQUEST_MAI_ID = "request_mai_id";
    
    private static String BS_FORM_UPLOAD_PUBKEYFILE = "pubkeyfile";
    private static String BS_FORM_UPLOAD_DATAFILE = "datafile";
    private static String BS_FORM_UPLOAD_SIGFILE = "sigfile";
    
	private static HttpClient client;
	private static String servername;
	
	private static CryptoStore cryptostore;
	private static ServerTalker instance;
	
	public static synchronized ServerTalker getInstance(String s, CryptoStore cs) {
        if (instance == null) {
            instance = new ServerTalker(s, cs);
        }

        return instance;
    }
	
	private ServerTalker(String s, CryptoStore cs) {
		client = new DefaultHttpClient();
		servername = s;
		cryptostore = cs;
	}
	
	public void setServerName(String s) {
		servername = s;
	}
	
	public String uploadPublicKey() throws ClientProtocolException, IOException {
		
		String serverAnswer = "Server did not answer";
		File keyFile = cryptostore.createArmoredPublicKeyFile();
		String postURL = servername + BS_URL_UPLOAD + BS_URL_UPLOAD_MAI_PUBKEY + cryptostore.getMaiId();
		
        HttpPost post = new HttpPost(postURL);
        FileBody keyFileBody = new FileBody(keyFile);
        
        MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
        reqEntity.addPart(BS_FORM_UPLOAD_PUBKEYFILE, keyFileBody);
        post.setEntity(reqEntity);
        
        HttpResponse response;
		response = client.execute(post);
        HttpEntity resEntity = response.getEntity();
        keyFile.delete();
        
        if (resEntity != null) {    
        	serverAnswer = EntityUtils.toString(resEntity);
        }
        
        return serverAnswer; 
	}
	
	public String signAndUploadData(String ea_id, String data)
			throws ClientProtocolException, IOException {
		
		SignedDataFiles sdf = cryptostore.createSignedDataFiles(data);
        
		String serverAnswer = "Server did not answer";
		String postURL = servername + BS_URL_UPLOAD + BS_URL_UPLOAD_EA_DATA + cryptostore.getMaiId() + "/" + ea_id;
		
        HttpPost post = new HttpPost(postURL);
        FileBody sigFileBody = new FileBody(sdf.signature);
        FileBody dataFileBody = new FileBody(sdf.data);
        
        MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
        reqEntity.addPart(BS_FORM_UPLOAD_SIGFILE, sigFileBody);  
        reqEntity.addPart(BS_FORM_UPLOAD_DATAFILE, dataFileBody);
        post.setEntity(reqEntity);
        
        HttpResponse response;
		response = client.execute(post);
        HttpEntity resEntity = response.getEntity();
        sdf.deleteFiles();
        
        if (resEntity != null) {    
        	serverAnswer = EntityUtils.toString(resEntity);
        }
        
        return serverAnswer;
	}
	
	public String requestMaiId() throws ClientProtocolException, IOException {
		String serverAnswer = null;
		String getURL = servername + BS_URL_UPLOAD + BS_URL_UPLOAD_REQUEST_MAI_ID;
		
        HttpGet get = new HttpGet(getURL);
        
        HttpResponse response;
        response = client.execute(get);
        HttpEntity resEntity = response.getEntity();
        
        if (resEntity != null) {
        	serverAnswer = EntityUtils.toString(resEntity);
        }
        
        return serverAnswer;
	}
	
}